package com.wisdytech.ccdserver.common.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.wisdytech.common.execption.BaseErrorCode;
import com.wisdytech.common.execption.BaseServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.List;


/**
 * @Description: 通过注解生成对应的excel文件
 * @Param: * @param null
 * @return: * @return null
 * @Author: SV00216491
 * @Date: 2024/4/18  14:36
 */


@Slf4j
public class ExcelUtil {
    public static MultipartFile exportToMinIO(List<?> list, Class<?> clazz, String sheetName, String fileName) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).build();
        MultipartFile file = null;
        try {
            // 这里注意 单独设置sheet的表头
            WriteSheet writeSheet = EasyExcel.writerSheet(0, sheetName).head(clazz).build();
            excelWriter.write(list, writeSheet);
        } catch (Exception e) {
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
                file = new MockMultipartFile("SendLocalitiesEmail",
                        fileName + ".xlsx",
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.xlsx", byteArrayOutputStream.toByteArray());
            }
        }
        return file;
    }

    /**
     * 将不同的实体类导出后写入不同的sheet中，所有的list顺序必须保持一致
     *
     * @param classes       实体类集合
     * @param dataList      数据集合
     * @param sheetNameList sheet名字集合
     * @param rowLimit      每个sheet的数量上限，如果超出上限，就会多分一个sheet
     * @throws Exception
     */
    public static MultipartFile writeExcelMultipleTablesNew(List<Class> classes, List<List> dataList, List<String> sheetNameList, int rowLimit, String fileName) throws Exception {
        ExcelWriter build = null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        MultipartFile multipartFile = null;

        //设置文件头部字体样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 9);
        headWriteFont.setFontName("微软雅黑");
        headWriteFont.setColor(IndexedColors.BLACK.index);
        //设置文本是否应换行
        headWriteCellStyle.setWrapped(false);
        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE.index);
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        headWriteCellStyle.setWriteFont(headWriteFont);
        //设置文件内容字体样式
        WriteCellStyle contentStyle = new WriteCellStyle();
        WriteFont contextWriteFont = new WriteFont();
        contextWriteFont.setFontName("微软雅黑");
        contextWriteFont.setFontHeightInPoints((short) 9);
        contentStyle.setWriteFont(contextWriteFont);
        try {
            build = EasyExcel.write(outputStream).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentStyle))
                    .registerWriteHandler(new ExcelCustomHandler())
                    .build();
//            sheet总页数
            int sheetTotalNum = 0;
            // 去调用写入,循环次数为list的size
            for (int i = 0; i < classes.size(); i++) {
                String sheetName = sheetNameList.get(i);
//                每种class会根据前端传进来的总页数进行限制，这是分页数量
                int sheetInnerNum = 0;
//                取出具体的list
                List list = dataList.get(i);
//                总页数
                int pageTotalNum = list.size() / rowLimit;
//                取余数量，如果不为0，总页数要加1
                if (0 != list.size() % rowLimit) {
                    pageTotalNum++;
                }
                for (int j = 0; j < pageTotalNum; j++) {
                    // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。
                    WriteSheet writeSheet = EasyExcel.writerSheet(sheetTotalNum, sheetName + (sheetInnerNum + 1)).head(classes.get(i)).build();

                    int fromIndex = sheetInnerNum * rowLimit;
                    List innerPageData = null;
                    try {
                        innerPageData = list.subList(fromIndex, fromIndex + rowLimit);
                    } catch (IndexOutOfBoundsException e) {
                        innerPageData = list.subList(fromIndex, list.size());
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                        throw new BaseServiceException(BaseErrorCode.ErrorCode.SYSTEM_ERROR);
                    } finally {
                        build.write(innerPageData, writeSheet);
                        sheetTotalNum++;
                        sheetInnerNum++;
                    }
                }
            }
            if (build != null) {
                build.finish();
                byte[] bytes = outputStream.toByteArray();
                ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
                multipartFile = new MockMultipartFile(fileName,
                        fileName + ".xlsx",
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.xlsx", inputStream);
            }
            return multipartFile;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BaseServiceException(BaseErrorCode.ErrorCode.SYSTEM_ERROR);
        } finally {
            outputStream.close();
        }
    }

}
